package com.swapper.regexp;

/**
 * The character helper.
 * Unicode's character(U+0000-U+10FFFF) util methods.
 */
final class CharacterHelper {
  private CharacterHelper() {
    throw new UnsupportedOperationException(getClass().getSimpleName());
  }

  /**
   * Returns {@code true} if the {@code codePoint} is hexadecimal character.
   *
   * @param codePoint the character code point.
   * @return {@code true} if the {@code codePoint} is hexadecimal character.
   */
  public static boolean isHexCharacter(int codePoint) {
    return (codePoint >= '0' && codePoint <= '9')
      || (codePoint >= 'A' && codePoint <= 'F')
      || (codePoint >= 'a' && codePoint <= 'f');
  }

  /**
   * Gets decimal value form octal character code point.
   *
   * @param codePoint the octal character code point.
   * @return decimal value form octal character code point,
   * if {@code codePoint} is not an octal character, -1 is returned.
   */
  public static int codePointToOct(int codePoint) {
    if (codePoint >= '0' && codePoint <= '7') {
      return codePoint - '0';
    } else {
      return -1;
    }
  }

  /**
   * Gets decimal value form hexadecimal character code point.
   *
   * @param codePoint the hexadecimal character code point.
   * @return decimal value form hexadecimal character code point,
   * if {@code codePoint} is not a hexadecimal character, -1 is returned.
   */
  public static int codePointToHex(int codePoint) {
    if (codePoint >= '0' && codePoint <= '9') {
      return codePoint - '0';
    } else if (codePoint >= 'A' && codePoint <= 'F') {
      return 10 + codePoint - 'A';
    } else if (codePoint >= 'a' && codePoint <= 'f') {
      return 10 + codePoint - 'a';
    } else {
      return -1;
    }
  }

  /**
   * Gets character string from character code point.
   *
   * @param codePoint the character code point.
   * @return character string from character code point,
   * returns {@code null} if the character code point is invalid.
   */
  public static String codePointToString(int codePoint) {
    if (Character.isValidCodePoint(codePoint)) {
      if (Character.isSupplementaryCodePoint(codePoint)) {
        return new String(new char[]{
          Character.highSurrogate(codePoint),
          Character.lowSurrogate(codePoint),
        });
      } else {
        return Character.toString((char) codePoint);
      }
    }
    return null;
  }
}
